package com.firexxx.study.thread;

import com.firexxx.study.lock.monitor.JavaHeadParser;
import lombok.SneakyThrows;
import lombok.Synchronized;

import java.io.IOException;
import java.nio.channels.InterruptibleChannel;

/**
 * @description: TODO
 * @author: zhuangzhang2
 * @date: 2021-02-14 21:01
 */
public class ThreadMain {

    private static void threadOfNewState() {
        Thread thread = new Thread();
        System.out.println(thread.getState());
    }

    private static void threadOfRunnableState() {
        Thread thread = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Thread.sleep(1000);
            }
        });
        thread.start();
        System.out.println(thread.getState());
    }

    private static void threadOfRunnableState1() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Thread t = Thread.currentThread();
                System.out.println(Thread.currentThread().getId());
                System.out.println(JavaHeadParser.parse(t).toJson());
                synchronized (t) {
                    System.out.println(Thread.currentThread().getId());
                    System.out.println(JavaHeadParser.parse(t).toJson());
                    Thread thread1 = new Thread(new Runnable() {
                        @SneakyThrows
                        @Override
                        public void run() {
                            synchronized (t) {
                                System.out.println(Thread.currentThread().getId());
                                System.out.println(JavaHeadParser.parse(t).toJson());
                                t.wait(1000);
                            }
                            System.out.println(Thread.currentThread().getId());
                            System.out.println(JavaHeadParser.parse(t).toJson());
                        }
                    });
                    thread1.start();
                    t.wait(1000);
                }
                System.out.println(Thread.currentThread().getId());
                System.out.println(JavaHeadParser.parse(t).toJson());
            }
        });
        thread.start();
        Thread.sleep(100);
        System.out.println(thread.getState());
    }

    private static void threadOfBlockedState1() throws InterruptedException {
        Thread thread1 = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                synchronized (ThreadMain.class) {
                    System.out.println("1");
                    ThreadMain.class.wait();
                }
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                synchronized (ThreadMain.class) {
                    System.out.println("2");
                    Thread.sleep(10000);
                }
            }
        });
        thread1.start();
        thread2.start();
        Thread.sleep(100);
        System.out.println(thread1.getState());
//        thread1.interrupt();
        Thread.sleep(100);
        System.out.println(thread1.getState());
    }

    private static void threadOfBlockedState2() throws InterruptedException {
        InterruptibleChannel interruptibleChannel = new InterruptibleChannel() {
            @Override
            public void close() throws IOException {
                System.out.println("close");
            }

            @Override
            public boolean isOpen() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return false;
            }
        };

        interruptibleChannel.isOpen();
    }

    private static void threadOfTerminatedState() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    //wait和notify必须在synchronized中，否则会抛出IllegalMonitorStateException
                    throw new Exception();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        Thread.sleep(100);
        System.out.println(thread.getState());
    }

    private static void threadOfWaitingState() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    //wait和notify必须在synchronized中，否则会抛出IllegalMonitorStateException
                    synchronized (this) {
                        this.wait();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        Thread.sleep(100);
        System.out.println(thread.getState());
    }

    private static void threadOfTimedWaitingState() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    //wait和notify必须在synchronized中，否则会抛出IllegalMonitorStateException
                    synchronized (this) {
                        this.wait(1000);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        Thread.sleep(100);
        System.out.println(thread.getState());
    }

    //from TIMED_WAITING to RUNNABLE
    private static void threadOfTimedWaitingState1() throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    //wait和notify必须在synchronized中，否则会抛出IllegalMonitorStateException
                    synchronized (this) {
                        this.wait(1000);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                while (true) {
                    int a = 1;
                    a /= 100000;
                }
            }
        });
        thread.start();
        Thread.sleep(100);
        System.out.println(thread.getState());
        thread.interrupt();
        Thread.sleep(100);
        System.out.println(thread.getState());
    }

    public static void main(String[] args) throws InterruptedException {
//        threadOfNewState();
//        threadOfRunnableState();
          threadOfRunnableState1();
//        threadOfTimedWaitingState();
//        threadOfTimedWaitingState1();
//        threadOfWaitingState();
//        threadOfTerminatedState();
//        threadOfBlockedState1();
    }

}
